<?php
/**
 * @name Auth: Authorisation and Permission managment library extension
 * @version 2.3, December 24, 2011
 * @copyright &copy; 2006 Novachok, A.
 * @author iSnow (Novachok Alexandr) <novachok@ukr.net>
 * @package Functions Library
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
$_FUNC['serial']  = 20111224;
$_FUNC['version'] = "2.3";


/******************************************************************************
 *                           NETWORK FUNCTIONS                                *
 ******************************************************************************/

/**
 * Function to Get IP address of visitor
 *
 * @return string
 */
function get_ip()
{
   if(getenv('HTTP_X_FORWARDED_FOR'))
   {
      $ip=getenv('HTTP_X_FORWARDED_FOR');
   } else {
      $ip=getenv('REMOTE_ADDR');
   }

   return $ip;
}


/**
 * Make downloads of files
 * Can organize partially downloads
 *
 * @param string $file - file's path
 * @param sting $output_name - name for Agent
 * @param integer $allow_partilly
 * @return downloads
 */
function resume_download($file, $output_name, $allow_partilly)
{
   $ext = null;
   $range = 0;
   if(!is_file($file))
   {
      return false;
   }

   $filename = basename($file);
   $ext = strtolower(substr(strrchr($filename,"."),1));
   $filename = str_replace(' ', '_', $output_name);
   if($ext == null || $ext === false)
   {
      $ext = strtolower(substr(strrchr($output_name,"."),1));
   } else
   {
      $filename = $filename.'.'.$ext;
   }
   if(strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
   {
      $filename = preg_replace('/\./', '%de', $filename, substr_count($filename, '.') - 1);
   }
   $size = filesize($file);

   switch($ext)
   {
      case "exe": $mime = "application/octet-stream"; break;
      case "zip": $mime = "application/zip"; break;
      case "mp3": $mime = "audio/mpeg"; break;
      case "mpg": $mime = "video/mpeg"; break;
      case "avi": $mime = "video/x-msvideo"; break;
      case "mid":
      case "midi":
      case "kar": $mime = "audio/midi"; break;
      case "pdf": $mime = "application/pdf"; break;
      case "ogg": $mime = "application/ogg"; break;
      case "wav": $mime = "audio/x-wav"; break;
      case "jpg": $mime = "image/jpeg"; break;
      case "php":
      case "htm":
      case "html":
      case "txt": return false; break;

      default: $mime = "application/force-download";
   }

   if($allow_partilly == true)
   {
      header('Cache-Control: public');
      header('Content-Disposition: attachment; filename='.$filename);
      header('Content-Type: '.$mime);
      header("Content-Transfer-Encoding: binary");
      header('Accept-Ranges: bytes');
      if(isset($_SERVER['HTTP_RANGE']))
      {
         list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);
         str_replace($range, "-", $range);
         $new_length=$size-$range;
         header('HTTP/1.1 206 Partial Content');
         header('Content-Length: '.$new_length);
         header("Content-Range: bytes $range$size/$size");
      } else {
         header("Content-Range: bytes 0-$size/$size");
         header('Content-Length: '.$size);
      }

      $fp = fopen($file,"r");
      fseek($fp, $range);
      while(!feof($fp))
      {
         @set_time_limit(0);
         print(fread($fp,1024*8));
         flush();
      }
      fclose($fp);
   } else
   {
      header('Content-disposition: attachment; filename='.$filename);
      //header('Content-Type: application/force-download'); # didn't transfer MIME type, so i coment this, but, for now, should be more attend - may allow resume download
      header('Content-Type: '.$mime);
      header('Content-Transfer-Encoding: binary');
      header("Content-Length: ".$size);
      header("Pragma: no-cache");
      header("Expires: 0");

      readfile($file);
   }
}

/**
 * Upload Files to a Given Directory, Check if file exist and rename||replace downloaded
 *
 * @param string $filename - Original file name
 * @param string $destination - Destination of Downloads
 * @param string $tmp_name - Temporary downloaded filename
 * @param string $processing - What to do if File exist: RN - rename, RP - replace
 * @return filename || false
 */
function uploadfile($filename, $destination, $tmp_name, $processing = 'RN')
{
   if(is_uploaded_file($tmp_name))
   {
      $filename = basename($filename);

      if(substr($destination, 0, -1) == '/') $destination = substr($destination, 0 , strlen($destination) -1);

      if(substr($destination, 0, strlen($_SERVER['DOCUMENT_ROOT'])) != $_SERVER['DOCUMENT_ROOT'])
      {
         $destination = $_SERVER['DOCUMENT_ROOT'].$destination;
      } else
      {
         $destination = $destination;
      }

      $ext = (strpos($filename,'.')===false?'':'.'.substr(strrchr($filename, "."), 1));
      $base = substr($filename, 0, strlen($filename) - strlen($ext));
      $base = preg_replace("/[^a-z0-9_\.]/i", "_", $base);
      $base = preg_replace("/[_]{2,}/", "_", $base);
      $fullpath = $destination.'/'.$base.$ext;
      $filename = $base.$ext;

      switch ($processing)
      {
         case 'RP': // Replace
         if(file_exists($fullpath))
         {
            @unlink($fullpath);
         }
         break;

         case 'RN': // Rename
         default:
         if(file_exists($fullpath))
         {
            for($i=1; file_exists($fullpath); $i++)
            {
               $filename = $base.'['.$i.']'.$ext;
               $fullpath = $destination.'/'.$filename;
            }
         }
      }

      if(@move_uploaded_file($tmp_name, $fullpath))
      {
      	chmod($fullpath, 0644);
      	return $filename;
      }

      return false;
   } else
   {
      return false;
   }
}


function http_request(
    $method = 'GET',           /* Method */
    $host,                     /* Target IP/Hostname */ 
    $port = 80,                /* Target TCP port */ 
    $uri = '/',                /* Target URI */ 
    $getdata = array(),        /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */ 
    $postdata = array(),       /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */ 
    $cookie = array(),         /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */ 
    $custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */ 
    $timeout = 3000,           /* Socket timeout in milliseconds */ 
    $req_hdr = false,          /* Include HTTP request headers */ 
    $res_hdr = false           /* Include HTTP response headers */ 
    ) 
{ 
    $ret = ''; 
    $method = strtoupper($method); 
    $cookie_str = ''; 
    $getdata_str = count($getdata) ? '?' : ''; 
    $postdata_str = ''; 

    foreach ($getdata as $k => $v) 
                $getdata_str .= urlencode($k) .'='. urlencode($v) . '&'; 

    $postdata_str = http_build_query($postdata);

    foreach ($cookie as $k => $v) 
        $cookie_str .= urlencode($k) .'='. urlencode($v) .'; '; 

    $crlf = "\r\n"; 
    $req = $method .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf; 
    $req .= 'Host: '. $host . $crlf; 
    $req .= 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:8.0) Gecko/20100101 Firefox/8.0' . $crlf; 
    $req .= 'Accept: application/json, text/javascript, */*; q=0.01' . $crlf; 
    $req .= 'Accept-Language: en-us,en;q=0.5' . $crlf; 
    $req .= 'Accept-Encoding: deflate' . $crlf; 
    $req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf; 
    $req .= 'Connection: keep-alive'. $crlf;

    foreach ($custom_headers as $k => $v) 
        $req .= $k .': '. $v . $crlf; 
        
    if (!empty($cookie_str)) 
        $req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf; 
        
    if ($method == 'POST' && !empty($postdata_str)) 
    {
        $req .= 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' . $crlf; 
        $req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf; 
        $req .= $postdata_str; 
    } 
    else $req .= $crlf; 
    
    if ($req_hdr) 
        $ret .= $req; 

    if (($fp = @fsockopen($host, $port, $errno, $errstr)) == false) 
        return "Error $errno: $errstr\n"; 
    
    stream_set_timeout($fp, 0, $timeout * 1000); 
    echo nl2br($req); exit();
    fputs($fp, $req); 
    while ($line = fgets($fp)) $ret .= $line; 
    fclose($fp); 
    var_dump('Returns', $ret);
    if (!$res_hdr) 
        $ret = substr($ret, strpos($ret, "\r\n\r\n") + 4); 
    
    return $ret; 
} 





/******************************************************************************
 *                           iMagick FUNCTIONS                                *
 ******************************************************************************/

function detect_iMagickVersion()
{
	$version = FALSE;
   if(class_exists('Imagick'))
   {
      $version = 'Imagick';
   } else
   {
      exec(IMAGICK .'convert -version', $respond);
      if($respond)
      {
         preg_match('/\s(([\d]{1})\.([\d]{1,3})\.([\d-]{1,4}))\s/', $respond[0], $matches);
         $version['version'] = $matches[2];
         $version['major']   = $matches[3];
         $version['minor']   = $matches[4];
         if(!$version['version'] && !$version['major'] && !$version['minor']) $version = FALSE;
      }
   }
   return $version;
}


/**
 * Resize Image using iMagic convert
 *
 * @param string $from    - source file
 * @param string $to      - destination file
 * @param integer $width  - width of destionation image
 * @param integer $height - height of destination image
 * @param string $mode    - Resize mode: 0 - by bigger side with renaming target on duplicates,
 *                                       1 - by smaller side with renaming target on duplicates,
 *                                       2 - by bigger side with replacing target on duplicates,
 *                                       3 - by smaller side with replacing target on duplicates
 */
function resize_iMagick($from, $to, $width, $height, $mode = 0)
{
   if(!file_exists($from) || $width == false || $height == false) return false;

   $iMagick_version = detect_iMagickVersion();

   if($mode < 2 && $from != $to && file_exists($to))
   {
      $file = DevideFileName($to);
      for($i=1; file_exists($to); $i++)
      {
         $filename = $file['base'] . '_' . $i . $file['ext'];
         $to = $file['dir'].'/'.$filename;
      }
   }

   if($iMagick_version == 'Imagick')
   {
      if($mode == 1 || $mode == 3)
      {
         $img_size = getimagesize($from);
         $s_ratio  = $img_size[0] / $img_size[1];
         $d_ratio  = $width / $height;

         if($s_ratio > $d_ratio || $s_ratio == $d_ratio)
         {
            $k = $height / $img_size[1];
            $width = round($img_size[0]*$k);
         } elseif($s_ratio < $d_ratio)
         {
            $k = $width / $img_size[0];
            $height = round($img_size[1]*$k);
         }
      }

      $image = new Imagick($from);
      $image->scaleImage($width, $height, true);
      $image->writeImage($to);
      
   } else
   {
      $g = $width.'x'.$height;
      switch ($mode)
      {
         case 0:
         case 2:
            $g .= '\>';
            break;

         case 1:
         case 3:
            if($iMagick_version['version'] < 6 || ($iMagick_version['version'] == 6 && $iMagick_version['major'] < 1))
            {
               $img_size = getimagesize($from);
               $s_ratio  = $img_size[0] / $img_size[1];
               $d_ratio  = $width / $height;
               if($s_ratio > $d_ratio || $s_ratio == $d_ratio)
               {
                  $k = $height / $img_size[1];
                  $width = round($img_size[0]*$k);
               } elseif($s_ratio < $d_ratio)
               {
                  $k = $width / $img_size[0];
                  $height = round($img_size[1]*$k);
               }


               $g = $width.'x'.$height;
            } else
            {
               $g .= '^';
            }
            break;
      }

      $exec_str = IMAGICK .'convert ' . $from . ' -resize ' . $g . ' -quality '. config::read('jpg_compression') .' ' . $to;
      passthru($exec_str, $o);
   }

   $img_size = getimagesize($to);
   $output['width'] = $img_size[0];
   $output['height'] = $img_size[1];

   return $output;
}


/**
 *
 * @param string $from - source path
 * @param string $to - destionation path
 * @param integer $width
 * @param integer $height
 * @param integer $x
 * @param integer $y
 * @return integer
 */
function crop_iMagick($from, $to, $width, $height, $x=0, $y=0)
{
   if(!file_exists($from) || $width == FALSE || $height == FALSE) return  FALSE;

   if($from != $to && file_exists($to))
   {
      $file = DevideFileName($to);
      for($i=1; file_exists($to); $i++)
      {
         $filename = $file['base'] . '_' . $i . $file['ext'];
         $to = $file['dir'].'/'.$filename;
      }
   }

   $iMagick_version = detect_iMagickVersion();

   if($iMagick_version == 'Imagick')
   {
      $image = new Imagick($from);
      $image->cropImage($width, $height, $x, $y);
      $image->writeImage($to);
   } else
   {
      $exec_str = IMAGICK .'convert '.$from.' -crop '.$width.'x'.$height.'+'.$x.'+'.$y.' -quality '. config::read('jpg_compression') .' '.$to;
      passthru($exec_str, $o);
   }

   return TRUE;
}







/******************************************************************************
 *                           UTF-8 FUNCTIONS                                  *
 ******************************************************************************/

/**
 * Convert win-1251 to utf-8
 *
 * @param string $str
 * @return string
 */
function cp1251_utf8($str)
{
   static $table = array(
      "\xA8" => "\xD0\x81",
      "\xB8" => "\xD1\x91",
      "\xA1" => "\xD0\x8E",
      "\xA2" => "\xD1\x9E",
      "\xAA" => "\xD0\x84",
      "\xAF" => "\xD0\x87",
      "\xB2" => "\xD0\x86",
      "\xB3" => "\xD1\x96",
      "\xBA" => "\xD1\x94",
      "\xBF" => "\xD1\x97",
      "\x8C" => "\xD3\x90",
      "\x8D" => "\xD3\x96",
      "\x8E" => "\xD2\xAA",
      "\x8F" => "\xD3\xB2",
      "\x9C" => "\xD3\x91",
      "\x9D" => "\xD3\x97",
      "\x9E" => "\xD2\xAB",
      "\x9F" => "\xD3\xB3",
   );

   return preg_replace('#[\x80-\xFF]#se',' "$0" >= "\xF0" ? "\xD1".chr(ord("$0")-0x70) : ("$0" >= "\xC0" ? "\xD0".chr(ord("$0")-0x30) : (isset($table["$0"]) ? $table["$0"] : ""))', $str);
}

/**
 * Convert  utf-8 to win-1251
 *
 * @param string $str
 * @return string
 */
function utf8_cp1251($str)
{
   static $table = array(
      "\xD0\x81" => "\xA8",
      "\xD1\x91" => "\xB8",
      "\xD0\x8E" => "\xA1",
      "\xD1\x9E" => "\xA2",
      "\xD0\x84" => "\xAA",
      "\xD0\x87" => "\xAF",
      "\xD0\x86" => "\xB2",
      "\xD1\x96" => "\xB3",
      "\xD1\x94" => "\xBA",
      "\xD1\x97" => "\xBF",
      "\xD3\x90" => "\x8C",
      "\xD3\x96" => "\x8D",
      "\xD2\xAA" => "\x8E",
      "\xD3\xB2" => "\x8F",
      "\xD3\x91" => "\x9C",
      "\xD3\x97" => "\x9D",
      "\xD2\xAB" => "\x9E",
      "\xD3\xB3" => "\x9F",
   );

   return preg_replace('#([\xD0-\xD1])([\x80-\xBF])#se', 'isset($table["$0"]) ? $table["$0"] : chr(ord("$2")+("$1" == "\xD0" ? 0x30 : 0x70))', $str);
}

function utf8_substr($str, $offset, $length = null)
{
    #в начале пробуем найти стандартные функции
    if (function_exists('mb_substr')) return mb_substr($str, $offset, $length, 'utf-8'); #(PHP 4 >= 4.0.6, PHP 5)
    if (function_exists('iconv_substr')) return iconv_substr($str, $offset, $length, 'utf-8'); #(PHP 5)
    #однократные паттерны повышают производительность!
    preg_match_all('/(?>[\x09\x0A\x0D\x20-\x7E]           # ASCII
                      | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte
                      |  \xE0[\xA0-\xBF][\x80-\xBF]       # excluding overlongs
                      | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
                      |  \xED[\x80-\x9F][\x80-\xBF]       # excluding surrogates
                      |  \xF0[\x90-\xBF][\x80-\xBF]{2}    # planes 1-3
                      | [\xF1-\xF3][\x80-\xBF]{3}         # planes 4-15
                      |  \xF4[\x80-\x8F][\x80-\xBF]{2}    # plane 16
                     )
                    /xs', $str, $m);
    if ($length !== null) $a = array_slice($m[0], $offset, $length);
    else $a = array_slice($m[0], $offset);
    return implode('', $a);
}


function utf8_convert_case($s, $mode)
{
    static $trans = array(
        #CASE_UPPER => CASE_LOWER
        #en (английский латиница)
        "\x41" => "\x61", #a
        "\x42" => "\x62", #b
        "\x43" => "\x63", #c
        "\x44" => "\x64", #d
        "\x45" => "\x65", #e
        "\x46" => "\x66", #f
        "\x47" => "\x67", #g
        "\x48" => "\x68", #h
        "\x49" => "\x69", #i
        "\x4a" => "\x6a", #j
        "\x4b" => "\x6b", #k
        "\x4c" => "\x6c", #l
        "\x4d" => "\x6d", #m
        "\x4e" => "\x6e", #n
        "\x4f" => "\x6f", #o
        "\x50" => "\x70", #p
        "\x51" => "\x71", #q
        "\x52" => "\x72", #r
        "\x53" => "\x73", #s
        "\x54" => "\x74", #t
        "\x55" => "\x75", #u
        "\x57" => "\x77", #w
        "\x56" => "\x76", #v
        "\x58" => "\x78", #x
        "\x59" => "\x79", #y
        "\x5a" => "\x7a", #z

        #ru (русский кириллица)
        "\xd0\x81" => "\xd1\x91", #ё
        "\xd0\x90" => "\xd0\xb0", #а
        "\xd0\x91" => "\xd0\xb1", #б
        "\xd0\x92" => "\xd0\xb2", #в
        "\xd0\x93" => "\xd0\xb3", #г
        "\xd0\x94" => "\xd0\xb4", #д
        "\xd0\x95" => "\xd0\xb5", #е
        "\xd0\x96" => "\xd0\xb6", #ж
        "\xd0\x97" => "\xd0\xb7", #з
        "\xd0\x98" => "\xd0\xb8", #и
        "\xd0\x99" => "\xd0\xb9", #й
        "\xd0\x9a" => "\xd0\xba", #к
        "\xd0\x9b" => "\xd0\xbb", #л
        "\xd0\x9c" => "\xd0\xbc", #м
        "\xd0\x9d" => "\xd0\xbd", #н
        "\xd0\x9e" => "\xd0\xbe", #о
        "\xd0\x9f" => "\xd0\xbf", #п

        "\xd0\xa0" => "\xd1\x80", #р
        "\xd0\xa1" => "\xd1\x81", #с
        "\xd0\xa2" => "\xd1\x82", #т
        "\xd0\xa3" => "\xd1\x83", #у
        "\xd0\xa4" => "\xd1\x84", #ф
        "\xd0\xa5" => "\xd1\x85", #х
        "\xd0\xa6" => "\xd1\x86", #ц
        "\xd0\xa7" => "\xd1\x87", #ч
        "\xd0\xa8" => "\xd1\x88", #ш
        "\xd0\xa9" => "\xd1\x89", #щ
        "\xd0\xaa" => "\xd1\x8a", #ъ
        "\xd0\xab" => "\xd1\x8b", #ы
        "\xd0\xac" => "\xd1\x8c", #ь
        "\xd0\xad" => "\xd1\x8d", #э
        "\xd0\xae" => "\xd1\x8e", #ю
        "\xd0\xaf" => "\xd1\x8f", #я

        #tt (татарский, башкирский кириллица)
        "\xd2\x96" => "\xd2\x97", #ж с хвостиком    &#1174; => &#1175;
        "\xd2\xa2" => "\xd2\xa3", #н с хвостиком    &#1186; => &#1187;
        "\xd2\xae" => "\xd2\xaf", #y                &#1198; => &#1199;
        "\xd2\xba" => "\xd2\xbb", #h мягкое         &#1210; => &#1211;
        "\xd3\x98" => "\xd3\x99", #э                &#1240; => &#1241;
        "\xd3\xa8" => "\xd3\xa9", #o перечеркнутое  &#1256; => &#1257;

        #uk (украинский кириллица)
        "\xd2\x90" => "\xd2\x91",  #г с хвостиком
        "\xd0\x84" => "\xd1\x94",  #э зеркальное отражение
        "\xd0\x86" => "\xd1\x96",  #и с одной точкой
        "\xd0\x87" => "\xd1\x97",  #и с двумя точками

        #be (белорусский кириллица)
        "\xd0\x8e" => "\xd1\x9e",  #у с подковой над буквой

        #tr,de,es (турецкий, немецкий, испанский, французский латиница)
        "\xc3\x84" => "\xc3\xa4", #a умляут          &#196; => &#228;  (турецкий)
        "\xc3\x87" => "\xc3\xa7", #c с хвостиком     &#199; => &#231;  (турецкий, французский)
        "\xc3\x91" => "\xc3\xb1", #n с тильдой       &#209; => &#241;  (турецкий, испанский)
        "\xc3\x96" => "\xc3\xb6", #o умляут          &#214; => &#246;  (турецкий)
        "\xc3\x9c" => "\xc3\xbc", #u умляут          &#220; => &#252;  (турецкий, французский)
        "\xc4\x9e" => "\xc4\x9f", #g умляут          &#286; => &#287;  (турецкий)
        "\xc4\xb0" => "\xc4\xb1", #i c точкой и без  &#304; => &#305;  (турецкий)
        "\xc5\x9e" => "\xc5\x9f", #s с хвостиком     &#350; => &#351;  (турецкий)

        #hr (хорватский латиница)
        "\xc4\x8c" => "\xc4\x8d",  #c с подковой над буквой
        "\xc4\x86" => "\xc4\x87",  #c с ударением
        "\xc4\x90" => "\xc4\x91",  #d перечеркнутое
        "\xc5\xa0" => "\xc5\xa1",  #s с подковой над буквой
        "\xc5\xbd" => "\xc5\xbe",  #z с подковой над буквой

        #fr (французский латиница)
        "\xc3\x80" => "\xc3\xa0",  #a с ударением в др. сторону
        "\xc3\x82" => "\xc3\xa2",  #a с крышкой
        "\xc3\x86" => "\xc3\xa6",  #ae совмещенное
        "\xc3\x88" => "\xc3\xa8",  #e с ударением в др. сторону
        "\xc3\x89" => "\xc3\xa9",  #e с ударением
        "\xc3\x8a" => "\xc3\xaa",  #e с крышкой
        "\xc3\x8b" => "\xc3\xab",  #ё
        "\xc3\x8e" => "\xc3\xae",  #i с крышкой
        "\xc3\x8f" => "\xc3\xaf",  #i умляут
        "\xc3\x94" => "\xc3\xb4",  #o с крышкой
        "\xc5\x92" => "\xc5\x93",  #ce совмещенное
        "\xc3\x99" => "\xc3\xb9",  #u с ударением в др. сторону
        "\xc3\x9b" => "\xc3\xbb",  #u с крышкой
        "\xc5\xb8" => "\xc3\xbf",  #y умляут

        #xx (другой язык)
        #"" => "",  #

    );
    #d($trans);

    #вариант с str_replace() должен работать быстрее, чем с strtr()
    if ($mode == CASE_UPPER)
    {
        if (function_exists('mb_strtoupper'))   return mb_strtoupper($s, 'utf-8');
        if (preg_match('/^[\x00-\x7e]*$/', $s)) return strtoupper($s); #может, так быстрее?
        return strtr($s, array_flip($trans));
    }
    elseif ($mode == CASE_LOWER)
    {
        if (function_exists('mb_strtolower'))   return mb_strtolower($s, 'utf-8');
        if (preg_match('/^[\x00-\x7e]*$/', $s)) return strtolower($s); #может, так быстрее?
        return strtr($s, $trans);
    }
    else
    {
        trigger_error('Parameter 2 should be a constant of CASE_LOWER or CASE_UPPER!', E_USER_WARNING);
        return $s;
    }
    return $s;
}

function utf8_lowercase($s)
{
    return utf8_convert_case($s, CASE_LOWER);
}

function utf8_uppercase($s)
{
    return utf8_convert_case($s, CASE_UPPER);
}

function utf8_strlen($str)
{
    if (function_exists('mb_strlen')) return mb_strlen($str, 'utf-8');
    if (function_exists('iconv_strlen')) return iconv_strlen($str, 'utf-8');
    return strlen(utf8_decode($str));
}



/******************************************************************************
 *                           ARRAY FUNCTIONS                                  *
 ******************************************************************************/
 
 
/**
 * ORDER BY ARRAY'S ELEMENT 'position'
 * @param integer $a
 * @param integer $b
 * @return bool
 */
function pSort($a, $b)
{
   if ($a['position'] == $b['position'])
      return 0;
   return ($a['position'] < $b['position']) ? -1 : 1;
}


/**
 * Deduct one array from other by values which present in both
 *
 * @param array $source - Source array
 * @param array $deduct - Slice array
 * @return array
 */
function deduct_array($source, $deduct)
{
   foreach($source as $key=>$value)
   {
      if(!in_array($value, $deduct))
      {
         $result[] = $value;
      }
   }
   return $result;
}


/**
 * Recursion search for needle in haystack and return TRUE in success case, FALSE in oposite.
 *
 * @param string|array $needle
 * @param array $haystack
 * @param bool $type
 * @return bool
 */
function inArray_Recurse($needle = false, $haystack = false, $type = false)
{
   $result = false;
   if($needle == false || $haystack == false || !is_array($haystack)) return false;

   if(($result = in_array($needle, $haystack, $type)) != false)
   {
      $result = true;
   } else
   {
      foreach($haystack AS $value)
      {
         if(($result = inArray_Recurse($needle,$value, $type)) != false) break;
      }
   }

   return $result;
}


/**
 * Returns all the keys to all the needles found and put them (path to them) in an array.
 *
 * @param string $needle
 * @param array $haystack
 * @param integer $a
 * @param array $nodes_temp
 * @return array
 */
function array_search_recursive($needle, $haystack, $a=0, $nodes_temp=array())
{
   global $nodes_found;
   $a++;
   foreach ($haystack as $key1=>$value1)
   {
      $nodes_temp[$a] = $key1;
      if (is_array($value1))
      {
         array_search_recursive($needle, $value1, $a, $nodes_temp);
      } elseif($value1 == $needle)
      {
         $nodes_found[] = $nodes_temp;
      }
   }

   return $nodes_found;
}



/******************************************************************************
 *                           STRING FUNCTIONS                                 *
 ******************************************************************************/
 
 
 /**
 * Function for Roundign size of files.
 *
 * @param integer $size
 * @return string $size
 */
function RoundSizeBites(&$size)
{
   if($size == '')
   {
      $size = false;
   } else
   {
      if ($size >= 1048576) {
         $size = round($size / 1048576 * 100) / 100 . " Mb";
      } elseif ($size >= 1024) {
         $size = round($size / 1024 * 100) / 100 . " Kb";
      } else {
         $size = $size . " b";
      }
   }

   return $size;
}


function isHexColor(&$str)
{
        if(!preg_match('/^#?([\dA-F]{3}){1,2}$/i', $str))
        {
                $str = FALSE;
        }
        return $str;
}


function isBool(&$str)
{
   if($str == 1 || $str === 'yes' || $str === 'YES' || $str === true || $str === "true")
   {
      $str = true;
   } else
   {
      $str = false;
   }
   return $str;
}


/**
 * Generate Random string in length of $length
 *
 * @param integer $length
 * @return string $str
 */
function rand_string($length = 10, $params = array())
{
   $chars['digits'] = '0123456789';
   $chars['lower']  = 'abcdefghijklnmopqrstuvwxyz';
   $chars['upper']  = 'ABCDEFGHIJKLNMOPQRSTUVWXYZ';

   if(!empty($params['set']) && isset($chars[$params['set']])) $chars_list = $chars[$params['set']];
   else $chars_list = $chars['digits'] . $chars['lower'] . $chars['upper'];


   $chars_length = strlen($chars_list) - 1;
   (int)$length;
   if(!$length) $length = 10;
   $str = '';

   for($i = 0; $i < $length; $i++)
   {
      $str .= $chars_list{mt_rand (0,$chars_length)};
   }
   return $str;
}


function strtime2mysql($str)
{
   if(strpos($str, '.'))
   {
      $str = explode('.', $str);
   } elseif(strpos($str, '/'))
   {
      $str = explode('/', $str);
   } elseif(strpos($str, '-'))
   {
      $str = explode('-', $str);
   } elseif(strpos( $str, ','))
   {
      $str = explode(',', $str);
   } else
   {
      return false;
   }

   for($i=0,$t=count($str); $i<$t; $i++)
   {
      settype($str[$i], 'integer');
   }

   if(strlen($str[0] == 4))
   {
      $year = $str[0];
      $day = isset($str[2]) ? $str[2] : date('d');
   } else
   {
      $day = $str[0];
      $year = isset($str[2]) ? $str[2] : date('Y');
   }
   $month = isset($str[1]) ? $str[1] : date('m');

   if(checkdate($month, $day, $year)) return $year . '-' . $month . '-' . $day;

   return false;
}



function mysql2time($str)
{
   $return = NULL;
   $ss = $str;
   preg_match_all('/\d+/', $str, $r);
   if(!empty($str) && !empty($r))
   {
        $str = $r[0];
        if(!isset($str[3])) $str[3] = 0;
        if(!isset($str[4])) $str[4] = 0;
        if(!isset($str[5])) $str[5] = 0;
        $return = mktime(
         (empty($str[3]) ? 0 : $str[3]),
         (empty($str[4]) ? 0 : $str[4]),
         (empty($str[5]) ? 0 : $str[5]),
         $str[1],
         $str[2],
         $str[0]
      );
   }
   return $return;
}

 
 
 /******************************************************************************
 *                           FILESYSTEM FUNCTIONS                              *
 ******************************************************************************/
 
 /**
 * Get files list in Given directory
 *
 * @param string $dirName - Path of Given directory
 * @return array of Files names, directories and sym links in array:
 * returnet dates:  [dir]
 *                  [file]
 *                  [link]
 */
function getDirList ($dirName = '.')
{
   $content['file'] = false;
   $content['dir'] = false;
   $content['link'] = false;

   if(!substr($dirName, 0, 1) == '/')
   {
      $dirName = './'.$dirName;
   }
   $dirfd = opendir($dirName);
   if(!$dirfd) return false;

   while(($point = readdir($dirfd)) !== false)
   {
      if($point == '.' || $point == '..') continue;
      if(is_file($dirName.'/'.$point))
      {
         $content['file'][] = $point;
      }
      if(is_dir($dirName.'/'.$point))
      {
         $content['dir'][] = $point;

      }
      if(is_link($dirName.'/'.$point))
      {
         $content['link'][] = $point;
      }
   }
   closedir($dirfd);

   return $content;
}

/**
 * Make Name of uploaded file
 *
 * @param integer $int
 * @param string $ext - extention of file
 * @return string - file name
 */
function MakeFileName($int, $ext)
{
   if($int < 10)
   {
      $int = "000".$int;
   } elseif($int < 100)
   {
      $int = "00".$int;
   } elseif($int < 1000)
   {
      $int = "0".$int;
   }

   return $int.$ext;
}

function ClearFileName($filename)
{
   $ext = (strpos($filename,'.')===false?'':'.'.substr(strrchr($filename, "."), 1));
   $base = substr($filename, 0, strlen($filename) - strlen($ext));
   $base = preg_replace("/[^a-z0-9_\.]/i", "_", $base);
   $base = preg_replace("/[_]{2,}/", "_", $base);
   $filename = $base.$ext;
   return $filename;
}

function MoveFile($from, $to, $mode = 'RN')
{
   if(!file_exists($from)) return false;

   $dirname  = dirname($to);
   switch ($mode)
   {
      case 'RP': // Replace
      if(file_exists($to))
      {
         @unlink($to);
      }

      case 'RN': // Rename
      default:
      $filename = basename($to);
      if(file_exists($to))
      {
         $file = DevideFileName($to);
         for($i=1; file_exists($to); $i++)
         {
            $filename = $file['base'] . '_' . $i . $file['ext'];
            $to = $dirname.'/'.$filename;
         }
      }
   }

   @rename($from, $to);
   @unlink($from);

   return $filename;
}


function DevideFileName($filename)
{
        $file['path'] = $filename;
        $file['dir'] = dirname($filename);
   $filename = basename($filename);
   $file['ext']  = (strpos($filename, '.') === false ? '' : '.' . substr(strrchr($filename, '.'), 1));
   $file['base'] = substr($filename, 0, strlen($filename) - strlen($file['ext']));

   return $file;
}